{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "06a3bbec",
   "metadata": {},
   "source": [
    "下面用代码实现循环神经网络。首先读取数据，使用《小王子》这本书作为训练语料。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "58df11c1",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "115\n"
     ]
    },
    {
     "data": {
      "image/png": "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ly5d0rZt2750fKRrNypfWkpJSVFUVFSv4mtubu5V3vijlStX6tVXX9WxY8c0fvx4Z7/P55Mk1rIPtbW1am5uVm5urqKjoxUdHa3q6mr90z/9k6Kjo531Ye16S0tL0+233x6271vf+pY++OADSfx3dyV/93d/p3Xr1unBBx9UTk6OHn74Yf3t3/6tysvLJbF2kbiatfL5fOrq6lJLS0u/Y0az7u5uLViwQA0NDaqqqnKuxkiDt3ajMmRiY2OVm5urqqqqsP1VVVXKz88fplldn4wxWrFihfbt26ejR48qMzMz7HhmZqZ8Pl/YWnZ1dam6unrUr+XMmTNVX1+vuro6Z8vLy9Pf/M3fqK6uTrfeeitr14/vfve7vT7m/5vf/EYZGRmS+O/uSj799FPdcEP4/9qjoqKcj1+zdlfvatYqNzdXMTExYWOampp0+vTpUb+en0fM2bNndeTIESUnJ4cdH7S1i+BNySPK5x+/fuGFF8y7775riouLTXx8vDl37txwT+268thjjxmPx2OOHz9umpqanO3TTz91xmzcuNF4PB6zb98+U19fbx566KFR+1HOL/Onn1oyhrXrzxtvvGGio6PN008/bc6ePWteeuklM2bMGLN7925nDGvXt8WLF5uvfe1rzsev9+3bZ1JSUsyaNWucMazdF9rb283bb79t3n77bSPJbN682bz99tvOJ2uuZq2WLVtmxo8fb44cOWLeeustM2PGjFHx8esrrV13d7eZN2+eGT9+vKmrqwt7/giFQs45BmPtRm3IGGPMP//zP5uMjAwTGxtrvvOd7zgfKcYXJPW5bd++3Rlz6dIl89RTTxmfz2fcbreZMmWKqa+vH75JX8cuDxnWrn+vvfaayc7ONm6329x2223m5z//edhx1q5vbW1t5oknnjATJkwwN954o7n11lvNk08+Gfbkwdp94dixY33+P27x4sXGmKtbq87OTrNixQqTlJRk4uLizNy5c80HH3wwDI/mq3WltWtoaOj3+ePYsWPOOQZj7VzGGBPp5SIAAIDrwah8jwwAABgZCBkAAGAtQgYAAFiLkAEAANYiZAAAgLUIGQAAYC1CBgAAWIuQAQAA1iJkAACAtQgZAABgLUIGAABY6/8B1JIdsWQBRRgAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import os\n",
    "import sys\n",
    "\n",
    "# 导入前面实现的小王子数据集\n",
    "sys.path.append('./code')\n",
    "from my_utils import TheLittlePrinceDataset\n",
    "\n",
    "dataset = TheLittlePrinceDataset()\n",
    "\n",
    "# 统计每句话的长度\n",
    "sent_lens = []\n",
    "max_len = -1\n",
    "for sentence in dataset.tokens:\n",
    "    sent_len = len(sentence)\n",
    "    sent_lens.append(sent_len)\n",
    "    if sent_len > max_len:\n",
    "        max_len = sent_len\n",
    "        longest = sentence\n",
    "print(max_len)\n",
    "\n",
    "# 简单看一下语料中序列长度的分布\n",
    "import matplotlib.pyplot as plt\n",
    "plt.hist(sent_lens, bins=20)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf1e69d9",
   "metadata": {},
   "source": [
    "接下来建立词表，截断过长的序列，将序列填充（padding）到相同长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f25456ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1089 115\n",
      "(1088, 40)\n",
      "[  4  16  19 733 734 735 733 734 735   2  63  20   9   1   1   2   1  10\n",
      " 736 737   4  16  19  21   1   2  30 371 209  33 294   3   0   0   0   0\n",
      "   0   0   0   0]\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "dataset.build_vocab()\n",
    "sent_tokens = dataset.convert_tokens_to_ids()\n",
    "# 截断和填充\n",
    "max_len=40\n",
    "for i, tokens in enumerate(sent_tokens):\n",
    "    tokens = tokens[:max_len]\n",
    "    tokens += [dataset.token2id['<pad>']] * (max_len - len(tokens))\n",
    "    sent_tokens[i] = tokens\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "\n",
    "print(len(dataset.tokens), max([len(x) for x in dataset.tokens]))\n",
    "print(sent_tokens.shape)\n",
    "print(sent_tokens[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "06e6fb52",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "import torch\n",
    "from torch import nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "# 定义一个正态分布的函数用于初始化参数\n",
    "def normal(shape):\n",
    "    return torch.randn(size=shape) * 0.01\n",
    "\n",
    "class RNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(RNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 将输入与隐状态分别经过线性变化后相加\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            # 输入hidden_state与inputs经过线性变换后相加，\n",
    "            # 输出的hidden_state也是下一时刻输入的hidden_state\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        # 返回所有时刻的hidden_state: seq_len * batch_size * hidden_size\n",
    "        # 以及最后时刻的hidden_state（可能用于后续输入）: \n",
    "        # batch_size * hidden_size\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state,)\n",
    "\n",
    "# 在循环神经网络的基础上添加语言模型的输入输出、损失计算等\n",
    "class RNNLM(nn.Module):\n",
    "    def __init__(self, model, vocab_size, hidden_size):\n",
    "        super(RNNLM, self).__init__()\n",
    "        self.vocab_size = vocab_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.embedding = nn.Embedding(vocab_size, hidden_size)\n",
    "        self.model = model\n",
    "        self.W_hq = nn.Parameter(normal((hidden_size, vocab_size)))\n",
    "        self.b_q = nn.Parameter(torch.zeros(vocab_size))\n",
    "        \n",
    "    def forward(self, input_ids):\n",
    "        batch_size, seq_len = input_ids.shape\n",
    "        # input_ids形状为batch_size * seq_len，翻转为seq_len * batch_size，\n",
    "        # 将seq_len放在第一维方便计算\n",
    "        input_ids = torch.permute(input_ids, (1, 0))\n",
    "        # seq_len * batch_size * embed_size\n",
    "        embed = self.embedding(input_ids)\n",
    "        # batch_size * hidden_size\n",
    "        states = self.model.init_rnn_state(batch_size, self.hidden_size)\n",
    "        hiddens, _ = self.model(embed, states)\n",
    "    \n",
    "        hiddens = torch.flatten(hiddens[:-1], start_dim=0, end_dim=1)\n",
    "        output_states = torch.mm(hiddens, self.W_hq) + self.b_q\n",
    "        labels = torch.flatten(input_ids[1:], start_dim=0, end_dim=1)\n",
    "        loss_fct = nn.CrossEntropyLoss(ignore_index=0)\n",
    "        loss = loss_fct(output_states, labels)\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45a010aa",
   "metadata": {},
   "source": [
    "下面展示使用梯度裁剪的循环神经网络语言模型的训练代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "760da2e1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(1088, 40)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.3448: 100%|█| 200/200 [05:18<00:00,  1.59s\n"
     ]
    },
    {
     "data": {
      "image/png": "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MAysVmuTjjdN86THTvTz53/OarXy61//mvvuu++k5xISEhp8bd1nmaZ50uf+/HEfH58G3wua/u8hIqenFhWRDsrT05OamppGHbt06VJuueUWfvGLX9C3b1+ioqLYv39/6xb4M0FBQURGRrJ69Wr7YzU1NWzYsKHB1w0aNIitW7fSrVu3k26enp7241auXOnwupUrV9KrVy/A1nqSnp5ORkaG/flt27ZRWFhI7969AVtryY8//njG5ykiTaMWFZEOKikpiVWrVrF//378/f0JDQ095bHdunXjiy++YPLkyRiGwRNPPOGUloB7772XGTNm0K1bN3r16sWrr75Kfn5+va0ddR577DHOO+88pk2bxh133IGfnx/bt29n3rx5DjN7li1bxnPPPcfUqVOZN28en332GXPmzAFgzJgx9OvXjxtuuIGXXnqJ6upqfvOb33DBBRfYu8mefPJJLr74Yrp27cq1115LdXU13333HY8++mjr/qOInOXUoiLSQT388MNYLBaSk5OJiIhocLzJiy++SEhICMOHD2fy5MmMGzeOQYMGtWG1No899hjXXXcdN910E8OGDbOPN/H29j7la/r168fixYvZvXs3I0eOZODAgTzxxBNER0c7HPfQQw+xbt06Bg4cyDPPPMPf//53xo0bB9i6aGbPnk1ISAijRo1izJgxdOnShU8//dT++tGjR/PZZ5/x9ddfM2DAAC666CJWrVrVOv8QImJnmKfrABYRcRKr1Urv3r25+uqreeaZZ5r9PklJSTzwwAM88MADLVeciLQJdf2IiMs4cOAAP/zwAxdccAEVFRXMnDmTtLQ0rr/+emeXJiJOoq4fEXEZbm5uvPfee5xzzjmMGDGC1NRU5s+fbx/QKiJnH3X9iIiIiMtSi4qIiIi4LAUVERERcVkKKiIiIuKyFFRERETEZSmoiIiIiMtSUBERERGXpaAiIiIiLktBRURERFzW/wPHH456VwNKdQAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 梯度裁剪\n",
    "def grad_clipping(model, theta=1):\n",
    "    params = [p for p in model.parameters() if p.requires_grad]\n",
    "    norm = torch.sqrt(sum(torch.sum((p.grad ** 2)) for p in params))\n",
    "    if norm > theta:\n",
    "        for param in params:\n",
    "            param.grad[:] *= theta / norm\n",
    "    \n",
    "\n",
    "# 训练\n",
    "from torch.utils.data import DataLoader\n",
    "from torch.optim import SGD, Adam\n",
    "import numpy as np\n",
    "from tqdm import tqdm, trange\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "def train_rnn_lm(data_loader, rnn, vocab_size, hidden_size=128, \n",
    "                 epochs=200, learning_rate=1e-3):\n",
    "    # 准备模型、优化器等\n",
    "    rnn_lm = RNNLM(rnn, vocab_size, hidden_size)\n",
    "    optimizer = Adam(rnn_lm.parameters(), lr=learning_rate)\n",
    "    rnn_lm.zero_grad()\n",
    "    rnn_lm.train()\n",
    "\n",
    "    epoch_loss = []\n",
    "    with trange(epochs, desc='epoch', ncols=60) as pbar:\n",
    "        for epoch in pbar:\n",
    "            for step, batch in enumerate(data_loader):\n",
    "                loss = rnn_lm(batch)\n",
    "                pbar.set_description(f'epoch-{epoch}, ' + \\\n",
    "                    f'loss={loss.item():.4f}')\n",
    "                loss.backward()\n",
    "                grad_clipping(rnn_lm)\n",
    "                optimizer.step()\n",
    "                rnn_lm.zero_grad()\n",
    "            epoch_loss.append(loss.item())\n",
    "\n",
    "    epoch_loss = np.array(epoch_loss)\n",
    "    # 打印损失曲线\n",
    "    plt.plot(range(len(epoch_loss)), epoch_loss)\n",
    "    plt.xlabel('training epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()\n",
    "\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "print(sent_tokens.shape)\n",
    "vocab_size = len(dataset.token2id)\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long),\\\n",
    "    batch_size=16, shuffle=True)\n",
    "rnn = RNN(128, 128)\n",
    "train_rnn_lm(data_loader, rnn, vocab_size, hidden_size=128,\\\n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad30e705",
   "metadata": {},
   "source": [
    "接下来仿照循环神经网络实现长短期记忆，同样的接口使得我们可以重用之前的训练代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "1995d027",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.3615: 100%|█| 200/200 [14:59<00:00,  4.50s\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 长短期记忆\n",
    "def gate_params(input_size, hidden_size):\n",
    "    return (nn.Parameter(normal((input_size, hidden_size))),\n",
    "           nn.Parameter(normal((hidden_size, hidden_size))),\n",
    "           nn.Parameter(torch.zeros(hidden_size)))\n",
    "\n",
    "class LSTM(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(LSTM, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 输入门参数\n",
    "        self.W_xi, self.W_hi, self.b_i = gate_params(input_size, hidden_size)\n",
    "        # 遗忘门参数\n",
    "        self.W_xf, self.W_hf, self.b_f = gate_params(input_size, hidden_size)\n",
    "        # 输出门参数\n",
    "        self.W_xo, self.W_ho, self.b_o = gate_params(input_size, hidden_size)\n",
    "        # 候选记忆单元参数\n",
    "        self.W_xc, self.W_hc, self.b_c = gate_params(input_size, hidden_size)\n",
    "        \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),\n",
    "               torch.zeros((batch_size, hidden_size), dtype=torch.float))\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, cell_state = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            I = torch.sigmoid(torch.mm(inputs[step], self.W_xi) \\\n",
    "                + torch.mm(hidden_state, self.W_hi) + self.b_i)\n",
    "            F = torch.sigmoid(torch.mm(inputs[step], self.W_xf) \\\n",
    "                + torch.mm(hidden_state, self.W_hf) + self.b_f)\n",
    "            O = torch.sigmoid(torch.mm(inputs[step], self.W_xo) \\\n",
    "                + torch.mm(hidden_state, self.W_ho) + self.b_o)\n",
    "            C_tilda = torch.tanh(torch.mm(inputs[step], self.W_xc) \\\n",
    "                + torch.mm(hidden_state, self.W_hc) + self.b_c)\n",
    "            cell_state = F * cell_state + I * C_tilda\n",
    "            hidden_state = O * torch.tanh(cell_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state, cell_state)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "lstm = LSTM(128, 128)\n",
    "train_rnn_lm(data_loader, lstm, vocab_size, hidden_size=128, epochs=200, \n",
    "    learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6dafe1d",
   "metadata": {},
   "source": [
    "下面仿照长短期记忆实现门控循环单元。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "7c4f3992",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.2436: 100%|█| 200/200 [10:51<00:00,  3.26s\n"
     ]
    },
    {
     "data": {
      "image/png": "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HniAP/7xj2zatInzzz+fiRMnkpycbHZpZ23p0qVMnTqVNWvWsHDhQsrKyhg/fjwFBQWVzrvkkktITU11f3377bcmVVw3ffr0qVR/YmKi+7nnnnuOF198kVmzZrF+/XratWvHxRdfTF5enokVn53169dXur6FCxcCcO2117rPaW73sKCggAEDBjBr1qxqn6/NfXvggQf46quv+PTTT1mxYgX5+flcfvnlOByOprqM0zrT9RUWFrJx40Yef/xxNm7cyJdffsnu3bu54oorqpx75513Vrqv//nPf5qi/Fqp6R5Czb+XzfUeApWuKzU1lbfffhuLxcKvfvWrSud58j2szWeER/wtGlLJsGHDjLvvvrvSsZ49exq///3vTaqo4WRkZBiAsXTpUvexKVOmGJMnTzavqHp64oknjAEDBlT7nNPpNNq1a2c8++yz7mPFxcVGaGio8e9//7uJKmx4999/v9G1a1fD6XQahtH87yFgfPXVV+7Htblvx48fN7y9vY1PP/3Ufc7hw4cNq9VqfP/9901We22cen3VWbdunQEYBw8edB8bPXq0cf/99zducQ2kumus6feypd3DyZMnG2PHjq10rDndQ8Oo+hnhKX+LalE5SUlJCRs2bGD8+PGVjo8fP55Vq1aZVFXDycnJASA8PLzS8SVLlhAVFUX37t258847ycjIMKO8OtuzZw8xMTF07tyZG264gf379wOQlJREWlpapfvp6+vL6NGjm+39LCkp4cMPP+T222+vtBFnc7+HJ6vNfduwYQOlpaWVzomJiaFv377N8t7m5ORgsVgICwurdPyjjz4iMjKSPn368Lvf/a5ZtQTCmX8vW9I9TE9PZ/78+fz2t7+t8lxzuoenfkZ4yt+i6Uvoe5LMzEwcDgfR0dGVjkdHR5OWlmZSVQ3DMAweeughzjvvPPr27es+PnHiRK699lo6duxIUlISjz/+OGPHjmXDhg3NYpXF4cOH8/7779O9e3fS09N55plnGDlyJNu2bXPfs+ru58GDB80ot97mzp3L8ePHue2229zHmvs9PFVt7ltaWho+Pj60adOmyjnN7W+1uLiY3//+99x0002VNnu7+eab6dy5M+3ateOXX35hxowZbNmyxd315+lq+r1sSffwvffeIzg4mKuvvrrS8eZ0D6v7jPCUv0UFlWqc/P9UwXUDTz3W3EybNo2tW7eyYsWKSsevv/569/d9+/ZlyJAhdOzYkfnz51f5o/NEEydOdH/fr18/RowYQdeuXXnvvffcA/da0v186623mDhxYqWt0Zv7PTyduty35nZvS0tLueGGG3A6nbz22muVnrvzzjvd3/ft25du3boxZMgQNm7cyKBBg5q61LNW19/L5nYPAd5++21uvvlm/Pz8Kh1vTvfwdJ8RYP7forp+ThIZGYnNZquSAjMyMqokyubkvvvuY968eSxevJjY2Ngzntu+fXs6duzInj17mqi6hhUYGEi/fv3Ys2ePe/ZPS7mfBw8eZNGiRdxxxx1nPK+538Pa3Ld27dpRUlLCsWPHTnuOpystLeW6664jKSmJhQsXVmpNqc6gQYPw9vZutvf11N/LlnAPAZYvX86uXbtq/LsEz72Hp/uM8JS/RQWVk/j4+DB48OAqzXILFy5k5MiRJlVVd4ZhMG3aNL788kt++uknOnfuXONrsrKySElJoX379k1QYcOz2+3s2LGD9u3bu5tcT76fJSUlLF26tFnez3feeYeoqCguu+yyM57X3O9hbe7b4MGD8fb2rnROamoqv/zyS7O4txUhZc+ePSxatIiIiIgaX7Nt2zZKS0ub7X099feyud/DCm+99RaDBw9mwIABNZ7rafewps8Ij/lbbJAhuS3Ip59+anh7extvvfWWsX37duOBBx4wAgMDjQMHDphd2lm75557jNDQUGPJkiVGamqq+6uwsNAwDMPIy8szHn74YWPVqlVGUlKSsXjxYmPEiBFGhw4djNzcXJOrr52HH37YWLJkibF//35jzZo1xuWXX24EBwe779ezzz5rhIaGGl9++aWRmJho3HjjjUb79u2bzfVVcDgcRnx8vPHYY49VOt5c72FeXp6xadMmY9OmTQZgvPjii8amTZvcs15qc9/uvvtuIzY21li0aJGxceNGY+zYscaAAQOMsrIysy7L7UzXV1paalxxxRVGbGyssXnz5kp/m3a73TAMw9i7d6/x1FNPGevXrzeSkpKM+fPnGz179jQGDhzoEddnGGe+xtr+XjbXe1ghJyfHCAgIMGbPnl3l9c3hHtb0GWEYnvG3qKBSjVdffdXo2LGj4ePjYwwaNKjSdN7mBKj265133jEMwzAKCwuN8ePHG23btjW8vb2N+Ph4Y8qUKUZycrK5hZ+F66+/3mjfvr3h7e1txMTEGFdffbWxbds29/NOp9N44oknjHbt2hm+vr7GBRdcYCQmJppYcd0sWLDAAIxdu3ZVOt5c7+HixYur/d2cMmWKYRi1u29FRUXGtGnTjPDwcMPf39+4/PLLPea6z3R9SUlJp/3bXLx4sWEYhpGcnGxccMEFRnh4uOHj42N07drVmD59upGVlWXuhZ3kTNdY29/L5noPK/znP/8x/P39jePHj1d5fXO4hzV9RhiGZ/wtWsqLFREREfE4GqMiIiIiHktBRURERDyWgoqIiIh4LAUVERER8VgKKiIiIuKxFFRERETEYymoiIiIiMdSUBERERGPpaAiIrXSqVMnXn755Vqfv2TJEiwWC8ePH2+0mjzJ2f58RKR2vMwuQEQax5gxYzjnnHMa7MNz/fr1BAYG1vr8kSNHkpqaSmhoaIP8+yLSOimoiLRihmHgcDjw8qr5PwVt27Y9q/f28fFxbxMvIlJX6voRaYFuu+02li5dyj//+U8sFgsWi4UDBw64u2MWLFjAkCFD8PX1Zfny5ezbt4/JkycTHR1NUFAQQ4cOZdGiRZXe89SuDYvFwptvvslVV11FQEAA3bp1Y968ee7nT+36effddwkLC2PBggX06tWLoKAgLrnkElJTU92vKSsrY/r06YSFhREREcFjjz3GlClTuPLKK894vatWreKCCy7A39+fuLg4pk+fTkFBQaXan376aW666SaCgoKIiYnhlVdeqfQeycnJTJ48maCgIEJCQrjuuutIT0+vdM68efMYMmQIfn5+REZGcvXVV1d6vrCwkNtvv53g4GDi4+N5/fXXz1i3iNRMQUWkBfrnP//JiBEjuPPOO0lNTSU1NZW4uDj3848++igzZ85kx44d9O/fn/z8fC699FIWLVrEpk2bmDBhApMmTSI5OfmM/85TTz3Fddddx9atW7n00ku5+eabyc7OPu35hYWF/OMf/+CDDz5g2bJlJCcn87vf/c79/N///nc++ugj3nnnHVauXElubi5z5849Yw2JiYlMmDCBq6++mq1btzJnzhxWrFjBtGnTKp33/PPP079/fzZu3MiMGTN48MEHWbhwIeBqWbryyivJzs5m6dKlLFy4kH379nH99de7Xz9//nyuvvpqLrvsMjZt2sSPP/7IkCFDKv0bL7zwAkOGDGHTpk3ce++93HPPPezcufOM9YtIDRpsH2YR8SijR4827r///krHKraunzt3bo2v7927t/HKK6+4H3fs2NF46aWX3I8B409/+pP7cX5+vmGxWIzvvvuu0r917NgxwzAM45133jEAY+/eve7XvPrqq0Z0dLT7cXR0tPH888+7H5eVlRnx8fHG5MmTT1vnLbfcYtx1112Vji1fvtywWq1GUVGRu/ZLLrmk0jnXX3+9MXHiRMMwDOOHH34wbDZbpa3pt23bZgDGunXrDMMwjBEjRhg333zzaevo2LGj8etf/9r92Ol0GlFRUcbs2bNP+xoRqZlaVERaoVNbAgoKCnj00Ufp3bs3YWFhBAUFsXPnzhpbVPr37+/+PjAwkODgYDIyMk57fkBAAF27dnU/bt++vfv8nJwc0tPTGTZsmPt5m83G4MGDz1jDhg0bePfddwkKCnJ/TZgwAafTSVJSkvu8ESNGVHrdiBEj2LFjBwA7duwgLi6uUqtTxc+i4pzNmzczbty4M9Zy8s/DYrHQrl27M/48RKRmGkwr0gqdOnvnkUceYcGCBfzjH/8gISEBf39/rrnmGkpKSs74Pt7e3pUeWywWnE7nWZ1vGEaVYyc79flTOZ1O/u///o/p06dXeS4+Pv6Mr634twzDqPLvnnrc39//jO8FZ//zEJGaqUVFpIXy8fHB4XDU6tzly5dz2223cdVVV9GvXz/atWvHgQMHGrfAU4SGhhIdHc26devcxxwOB5s2bTrj6wYNGsS2bdtISEio8uXj4+M+b82aNZVet2bNGnr27Am4Wk+Sk5NJSUlxP799+3ZycnLo1asX4Got+fHHH+t9nSJydtSiItJCderUibVr13LgwAGCgoIIDw8/7bkJCQl8+eWXTJo0CYvFwuOPP25KS8B9993HzJkzSUhIoGfPnrzyyiscO3as2taOCo899hjnnnsuU6dO5c477yQwMJAdO3awcOHCSjN7Vq5cyXPPPceVV17JwoUL+eyzz5g/fz4AF110Ef379+fmm2/m5ZdfpqysjHvvvZfRo0e7u8meeOIJxo0bR9euXbnhhhsoKyvju+++49FHH23cH4pIK6cWFZEW6ne/+x02m43evXvTtm3bM443eemll2jTpg0jR45k0qRJTJgwgUGDBjVhtS6PPfYYN954I7feeisjRoxwjzfx8/M77Wv69+/P0qVL2bNnD+effz4DBw7k8ccfp3379pXOe/jhh9mwYQMDBw7k6aef5oUXXmDChAmAq4tm7ty5tGnThgsuuICLLrqILl26MGfOHPfrx4wZw2effca8efM455xzGDt2LGvXrm2cH4SIuFmMmjqARURM4nQ66dWrF9dddx1PP/10nd+nU6dOPPDAAzzwwAMNV5yINAl1/YiIxzh48CA//PADo0ePxm63M2vWLJKSkrjpppvMLk1ETKKuHxHxGFarlXfffZehQ4cyatQoEhMTWbRokXtAq4i0Pur6EREREY+lFhURERHxWAoqIiIi4rEUVERERMRjKaiIiIiIx1JQEREREY+loCIiIiIeS0FFREREPJaCioiIiHis/wesql/BoDwO5AAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 门控循环单元\n",
    "class GRU(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(GRU, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 更新门参数\n",
    "        self.W_xu, self.W_hu, self.b_u = gate_params(input_size, hidden_size)\n",
    "        # 重置门参数\n",
    "        self.W_xr, self.W_hr, self.b_r = gate_params(input_size, hidden_size)\n",
    "        # 候选隐状态参数\n",
    "        self.W_xh, self.W_hh, self.b_h = gate_params(input_size, hidden_size)\n",
    "        \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            U = torch.sigmoid(torch.mm(inputs[step], self.W_xu)\\\n",
    "                + torch.mm(hidden_state, self.W_hu) + self.b_u)\n",
    "            R = torch.sigmoid(torch.mm(inputs[step], self.W_xr)\\\n",
    "                + torch.mm(hidden_state, self.W_hr) + self.b_r)\n",
    "            H_tilda = torch.tanh(torch.mm(inputs[step], self.W_xh)\\\n",
    "                + torch.mm(R * hidden_state, self.W_hh) + self.b_h)\n",
    "            hidden_state = (1 - U) * hidden_state + U * H_tilda\n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(hiddens, dim=0), (hidden_state,)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "gru = GRU(128, 128)\n",
    "train_rnn_lm(data_loader, gru, vocab_size, hidden_size=128, epochs=200, \n",
    "    learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69537480",
   "metadata": {},
   "source": [
    "下面在循环神经网络的基础上实现多层循环神经网络。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "6eb2e0ed",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.4776: 100%|█| 200/200 [08:44<00:00,  2.62s\n"
     ]
    },
    {
     "data": {
      "image/png": "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sSEA7C5SUBERka53UoNp8/PzGTRoEACLFy/m4osv5sYbb+TUU09l1qxZx/0+CxYs8Hj8y1/+kueff561a9cycuTINufbbDZsNpv7cVVV1cmUL8dwyaRUquqb+MWS7fzm410UVjWwomXzwmunD+DR/24jp7SWZrsDP6t6D0VEpOuc1KdMWFgYpaWlAHz88cecddZZAAQFBVFfX3+0l3bIbrfzxhtvUFtby7Rp09o9Z9GiRURGRrq/UlOPf80QOTHXzxjIPXOGAPDa2jz2l9fjZzH4zsQUgv2tNNlNcsvqvFyliIj0dicVVM4++2yuv/56rr/+enbt2sW8efMA2Lp1KwMGDDih99q8eTNhYWEEBgZy00038e677zJixIh2z33wwQeprKx0f+Xn559M+XKcbp09mNevn0pypHOl2ykZMYQH+ZOZEArAHg2oFRGRLnZSQeW5555j2rRpHDp0iLfffpvY2FgAsrKyuPzyy0/ovYYOHcpXX33F2rVrufnmm7nmmmvYtm1bu+cGBga6B966vqRrnToojg9/dDqPLhjBry4cDcCg+DBAQUVERLqeYfrYVrlnnXUWmZmZ/PnPfz7muVVVVURGRlJZWanQ0o2eW76HJz/ayYXj+/O7S8d5uxwREelhTuTz+6RaVD788EM+++wz9+PnnnuOcePGccUVV1BeXn6UVx6baZoeA2bF92SqRUVERLrJSQWVe++91z3jZvPmzdx9992cd9557Nu3j7vuuuu43+fHP/4xq1evJicnh82bN/PQQw+xYsUKrrzyypMpS7rJoARnUNl7qMZjUTgREZHOdlLTk7Ozs90DXt9++23mz5/Pr371KzZu3Mh555133O9TVFTEVVddRUFBAZGRkYwZM4YPP/yQs88++2TKkm6SHhuCv9WgrtHOwcp6UqJDvF2SiIj0UicVVAICAqirc05NXbZsGVdffTUAMTExJ7S2yYsvvngyP168zN9qYUBsKLuLa9hTXKOgIiIiXeakun5OO+007rrrLn7+85+zfv169/TkXbt2kZKS0qkFim9ydf9onIqIiHSlkwoqzz77LH5+fvz73//m+eefp3///gB88MEHnHvuuZ1aoPim1uNUREREuspJdf2kpaXxv//9r83x3/3ud9+6IOkZXEFFe/6IiEhXOqmgAs4l7xcvXsz27dsxDIPhw4ezcOFCrFZrZ9Yn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w9336/HHHzcjIyPNd955x9y8ebN5+eWXm0lJST3m+lzsdruZlpZm3n///R7He+o9rK6uNjdt2mRu2rTJBMynnnrK3LRpk3vWy/Hct5tuuslMSUkxly1bZm7cuNGcPXu2OXbsWLO5udlbl+V2tOtramoyzz//fDMlJcX86quvPP42bTabaZqmuWfPHvOxxx4zN2zYYGZnZ5tLliwxhw0bZo4fP94nrs80j36Nx/t72VPvoUtlZaUZEhJiPv/8821e3xPu4bE+I0zTN/4WFVTa8dxzz5np6elmQECAOWHCBI/pvD0J0O7XSy+9ZJqmadbV1Zlz5swx4+PjTX9/fzMtLc285pprzLy8PO8WfgIuvfRSMykpyfT39zeTk5PNiy66yNy6dav7eYfDYT7yyCNmv379zMDAQPP00083N2/e7MWKT85HH31kAubOnTs9jvfUe7h8+fJ2fzevueYa0zSP777V19ebt956qxkTE2MGBweb8+fP95nrPtr1ZWdnd/i3uXz5ctM0TTMvL888/fTTzZiYGDMgIMDMzMw0b7/9drO0tNS7F9bK0a7xeH8ve+o9dPnzn/9sBgcHmxUVFW1e3xPu4bE+I0zTN/4WjZZiRURERHyOxqiIiIiIz1JQEREREZ+loCIiIiI+S0FFREREfJaCioiIiPgsBRURERHxWQoqIiIi4rMUVERERMRnKaiIyHEZMGAATz/99HGfv2LFCgzDoKKiostq8iUn+u8jIsfHz9sFiEjXmDVrFuPGjeu0D88NGzYQGhp63OdPnz6dgoICIiMjO+Xni0jfpKAi0oeZpondbsfP79j/KYiPjz+h9w4ICHBvEy8icrLU9SPSC1177bWsXLmS3//+9xiGgWEY5OTkuLtjPvroIyZNmkRgYCCrV69m7969LFy4kMTERMLCwpg8eTLLli3zeM8juzYMw+Cvf/0rF154ISEhIQwePJj33nvP/fyRXT8vv/wyUVFRfPTRRwwfPpywsDDOPfdcCgoK3K9pbm7m9ttvJyoqitjYWO6//36uueYaLrjggqNe7+eff87pp59OcHAwqamp3H777dTW1nrU/vOf/5wrrriCsLAwkpOTeeaZZzzeIy8vj4ULFxIWFkZERASXXHIJRUVFHue89957TJo0iaCgIOLi4rjooos8nq+rq+O6664jPDyctLQ0XnjhhaPWLSLHpqAi0gv9/ve/Z9q0adxwww0UFBRQUFBAamqq+/n77ruPRYsWsX37dsaMGUNNTQ3nnXcey5YtY9OmTZxzzjksWLCAvLy8o/6cxx57jEsuuYRvvvmG8847jyuvvJKysrIOz6+rq+M3v/kNf//731m1ahV5eXncc8897ud//etf8/rrr/PSSy+xZs0aqqqqWLx48VFr2Lx5M+eccw4XXXQR33zzDW+++SafffYZt956q8d5Tz75JGPGjGHjxo08+OCD/OhHP2Lp0qWAs2XpggsuoKysjJUrV7J06VL27t3LpZde6n79kiVLuOiii5g3bx6bNm3ik08+YdKkSR4/47e//S2TJk1i06ZN/PCHP+Tmm29mx44dR61fRI6h0/ZhFhGfMnPmTPOOO+7wOObaun7x4sXHfP2IESPMZ555xv04PT3d/N3vfud+DJg/+clP3I9rampMwzDMDz74wONnlZeXm6Zpmi+99JIJmHv27HG/5rnnnjMTExPdjxMTE80nn3zS/bi5udlMS0szFy5c2GGdV111lXnjjTd6HFu9erVpsVjM+vp6d+3nnnuuxzmXXnqpOXfuXNM0TfPjjz82rVarx9b0W7duNQFz/fr1pmma5rRp08wrr7yywzrS09PN733ve+7HDofDTEhIMJ9//vkOXyMix6YWFZE+6MiWgNraWu677z5GjBhBVFQUYWFh7Nix45gtKmPGjHF/HxoaSnh4OMXFxR2eHxISQmZmpvtxUlKS+/zKykqKioqYMmWK+3mr1crEiROPWkNWVhYvv/wyYWFh7q9zzjkHh8NBdna2+7xp06Z5vG7atGls374dgO3bt5OamurR6uT6t3Cd89VXX3HmmWcetZbW/x6GYdCvX7+j/nuIyLFpMK1IH3Tk7J17772Xjz76iN/85jcMGjSI4OBgLr74YhobG4/6Pv7+/h6PDcPA4XCc0PmmabY51tqRzx/J4XDwf//3f9x+++1tnktLSzvqa10/yzTNNj/3yOPBwcFHfS848X8PETk2taiI9FIBAQHY7fbjOnf16tVce+21XHjhhYwePZp+/fqRk5PTtQUeITIyksTERNavX+8+Zrfb2bRp01FfN2HCBLZu3cqgQYPafAUEBLjPW7t2rcfr1q5dy7BhwwBn60leXh75+fnu57dt20ZlZSXDhw8HnK0ln3zyybe+ThE5MWpREemlBgwYwLp168jJySEsLIyYmJgOzx00aBDvvPMOCxYswDAMHn74Ya+0BNx2220sWrSIQYMGMWzYMJ555hnKy8vbbe1wuf/++znllFO45ZZbuOGGGwgNDWX79u0sXbrUY2bPmjVreOKJJ7jgggtYunQpb731FkuWLAHgrLPOYsyYMVx55ZU8/fTTNDc388Mf/pCZM2e6u8keeeQRzjzzTDIzM7nssstobm7mgw8+4L777uvafxSRPk4tKiK91D333IPVamXEiBHEx8cfdbzJ7373O6Kjo5k+fToLFizgnHPOYcKECd1YrdP999/P5ZdfztVXX820adPc402CgoI6fM2YMWNYuXIlu3fvZsaMGYwfP56HH36YpKQkj/PuvvtusrKyGD9+PD//+c/57W9/yznnnAM4u2gWL15MdHQ0p59+OmeddRYDBw7kzTffdL9+1qxZvPXWW7z33nuMGzeO2bNns27duq75hxARN8M8VgewiIiXOBwOhg8fziWXXMLPf/7zk36fAQMGcOedd3LnnXd2XnEi0i3U9SMiPiM3N5ePP/6YmTNnYrPZePbZZ8nOzuaKK67wdmki4iXq+hERn2GxWHj55ZeZPHkyp556Kps3b2bZsmXuAa0i0veo60dERER8llpURERExGcpqIiIiIjPUlARERERn6WgIiIiIj5LQUVERER8loKKiIiI+CwFFREREfFZCioiIiLis/4f7tujYgXmHLMAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 多层循环神经网络\n",
    "class DeepRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size, num_layers, dropout=0.):\n",
    "        super(DeepRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        self.num_layers = num_layers\n",
    "        self._flat_weight_names = []\n",
    "        self._all_weights = []\n",
    "        self.drop = nn.Dropout(p=dropout)\n",
    "        # 定义每一层循环神经网络的参数，由于参数数量不固定，\n",
    "        # 因此使用统一的命名方法更方便调用和管理\n",
    "        for layer in range(num_layers):\n",
    "            W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "            W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "            b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "            layer_params = (W_xh, W_hh, b_h)\n",
    "            params_names = [f'W_xh_l{layer}', f'W_hh_l{layer}', \\\n",
    "                f'b_h_l{layer}']\n",
    "            \n",
    "            # 将新的参数加入到成员列表中\n",
    "            for name, param in zip(params_names, layer_params):\n",
    "                setattr(self, name, param)\n",
    "            self._flat_weight_names.extend(params_names)\n",
    "            self._all_weights.append(params_names)\n",
    "            input_size = hidden_size\n",
    "        self._flat_weights = [getattr(self, wn) if hasattr(self, wn) \\\n",
    "            else None for wn in self._flat_weight_names]\n",
    "    \n",
    "    def __setattr__(self, attr, value):\n",
    "        if hasattr(self, '_flat_weight_names') and \\\n",
    "            attr in self._flat_weight_names:\n",
    "            idx = self._flat_weight_names.index(attr)\n",
    "            self._flat_weights[idx] = value\n",
    "        super().__setattr__(attr, value)\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((self.num_layers, batch_size, hidden_size), \n",
    "            dtype=torch.float),)\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        layer_hidden_states, = states\n",
    "        layer_h_t = []\n",
    "        input_states = inputs\n",
    "        # 需要保存每一层的输出作为下一层的输入\n",
    "        for layer in range(self.num_layers):\n",
    "            hiddens = []\n",
    "            hidden_state = layer_hidden_states[layer]\n",
    "            for step in range(seq_len):\n",
    "                xh = torch.mm(input_states[step], \n",
    "                    getattr(self, f'W_xh_l{layer}'))\n",
    "                hh = torch.mm(hidden_state, getattr(self, f'W_hh_l{layer}'))\n",
    "                hidden_state = xh + hh + getattr(self, f'b_h_l{layer}')\n",
    "                hidden_state = self.drop(torch.tanh(hidden_state))\n",
    "                hiddens.append(hidden_state)\n",
    "            input_states = torch.stack(hiddens, dim=0)\n",
    "            layer_h_t.append(hidden_state)\n",
    "        return input_states, torch.stack(layer_h_t, dim=0)\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "deep_rnn = DeepRNN(128, 128, 2)\n",
    "train_rnn_lm(data_loader, deep_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f0f1be39",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "需要注意的是，双向循环神经网络在每个位置的输出同时包含了来自左边和右边的信息，也就是整个输入序列的信息。所以双向循环神经网络并不能用于语言模型，因为语言模型需要仅根据序列中每个词左边的信息来预测这个词。\n",
    "\n",
    "下面的双向循环神经网络是一个简单的示例，要求一次只能输入一个序列。如果想在一个批次中并行处理不同长度的输入序列以获得更高的运行效率，可以通过填充将不同长度的输入对齐。单向循环神经网络的填充较为简单，只需在每个序列末尾添加字符就可以。但是双向循环神经网络的填充更加复杂，正向和反向循环神经网络的读取顺序相反，难以保证两个方向的循环神经网络都填充在末尾，实现起来较为困难。\n",
    "解决方案参考PyTorch中的pack_padded_sequence和pad_packed_sequence。双向循环神经网络不能用于训练语言模型，因此不再提供训练示例代码。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0344d588",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 双向循环神经网络\n",
    "class BiRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(BiRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 正向循环神经网络参数\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "        # 反向循环神经网络参数\n",
    "        self.W_xh_reverse = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh_reverse = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h_reverse = nn.Parameter(torch.zeros(hidden_size))\n",
    "        \n",
    "    # 分别为正向和反向循环神经网络准备初始状态\n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size), dtype=torch.float),\n",
    "               torch.zeros((batch_size, hidden_size), dtype=torch.float))\n",
    "    \n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, reverse_hidden_state = states\n",
    "        hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            hiddens.append(hidden_state)\n",
    "        reverse_hiddens = []\n",
    "        for step in range(seq_len-1, -1, -1):\n",
    "            xh = torch.mm(inputs[step], self.W_xh_reverse)\n",
    "            hh = torch.mm(reverse_hidden_state, self.W_hh_reverse)\n",
    "            reverse_hidden_state = xh + hh + self.b_h_reverse\n",
    "            reverse_hidden_state = torch.tanh(reverse_hidden_state)\n",
    "            reverse_hiddens.insert(0, reverse_hidden_state)\n",
    "        # 将正向和反向循环神经网络输出的隐状态拼接在一起\n",
    "        combined_hiddens = []\n",
    "        for h1, h2 in zip(hiddens, reverse_hiddens):\n",
    "            combined_hiddens.append(torch.cat([h1, h2], dim=-1))\n",
    "        return torch.stack(combined_hiddens, dim=0), ()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b79ef2c6",
   "metadata": {},
   "source": [
    "下面实现一个带有缩放点乘注意力的循环神经网络，并用其训练语言模型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b5c32275",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=0.9413: 100%|█| 200/200 [08:34<00:00,  2.57s\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "class AttentionRNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_size):\n",
    "        super(AttentionRNN, self).__init__()\n",
    "        self.input_size = input_size\n",
    "        self.hidden_size = hidden_size\n",
    "        # 循环神经网络参数\n",
    "        self.W_xh = nn.Parameter(normal((input_size, hidden_size)))\n",
    "        self.W_hh = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_h = nn.Parameter(torch.zeros(hidden_size))\n",
    "    \n",
    "    def init_rnn_state(self, batch_size, hidden_size):\n",
    "        return (torch.zeros((batch_size, hidden_size),\\\n",
    "            dtype=torch.float),)\n",
    "    \n",
    "    # 缩放点乘注意力\n",
    "    def attention(self, query, keys, values):\n",
    "        \"\"\"\n",
    "        query: batch_size * hidden_size\n",
    "        keys/values: batch_size * prev_len * hidden_size\n",
    "        \"\"\"\n",
    "        # batch_size * 1 * hidden_size\n",
    "        query = torch.unsqueeze(query, 1)\n",
    "        # batch_size * hidden_size * prev_len\n",
    "        keys = torch.permute(keys, (0, 2, 1))\n",
    "        # batch_size * 1 * prev_len\n",
    "        attention_scores = torch.bmm(query, keys) / np.sqrt(\\\n",
    "            self.hidden_size)\n",
    "        # batch_size * 1 * prev_len\n",
    "        attention_weights = F.softmax(attention_scores, dim=1)\n",
    "        # batch_size * hidden_size\n",
    "        attention_state = torch.squeeze(torch.bmm(attention_weights,\\\n",
    "            values))\n",
    "        return attention_state\n",
    "\n",
    "    def forward(self, inputs, states):\n",
    "        seq_len, batch_size, _ = inputs.shape\n",
    "        hidden_state, = states\n",
    "        hiddens = []\n",
    "        attention_hiddens = []\n",
    "        for step in range(seq_len):\n",
    "            xh = torch.mm(inputs[step], self.W_xh)\n",
    "            hh = torch.mm(hidden_state, self.W_hh)\n",
    "            hidden_state = xh + hh + self.b_h\n",
    "            hidden_state = torch.tanh(hidden_state)\n",
    "            \n",
    "            if step > 0:\n",
    "                # batch_size * hidden_size\n",
    "                query = hidden_state\n",
    "                # batch_size * prev_len * hidden_size\n",
    "                keys = values = torch.permute(torch.stack(hiddens,\\\n",
    "                    dim=0), (1, 0, 2))\n",
    "                \n",
    "                attention_state = self.attention(query, keys, values)                \n",
    "                attention_hiddens.append(attention_state)\n",
    "            else:\n",
    "                # 第0步，历史隐状态为空，无法进行注意力运算，\n",
    "                # 直接用隐状态填充\n",
    "                attention_hiddens.append(hidden_state)\n",
    "                \n",
    "            hiddens.append(hidden_state)\n",
    "        return torch.stack(attention_hiddens, dim=0), \\\n",
    "            (attention_state,)\n",
    "    \n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, dtype=torch.long), \n",
    "    batch_size=16, shuffle=True)\n",
    "\n",
    "attention_rnn = AttentionRNN(128, 128)\n",
    "train_rnn_lm(data_loader, attention_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c95d2f4b",
   "metadata": {},
   "source": [
    "下面是多头注意力的代码实现。我们在实现AttentionRNN时将注意力计算封装在成员函数里面，因此实现多头注意力时可以直接继承AttentionRNN类，只用改写构造函数和attention()成员方法即可。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "6373e7ab",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-199, loss=1.1537: 100%|█| 200/200 [26:02<00:00,  7.81s\n"
     ]
    },
    {
     "data": {
      "image/png": "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XHLJJVi/fj3279+Piy66CJdffjmKiop6/DnPPPMMrr/+ehw6dAiXXHIJVqxYgbq6um6vb2trw5/+9Ce888472Lx5M4qKivDoo48q9//hD3/Af/7zH7zxxhv47rvv0NTUhM8++6zHMRw+fBgXXXQRrrnmGhw6dAgffvghtm7divvuu8/ruj/+8Y+YNm0a9u3bhyeeeAI//elPsW7dOgBSZemqq65CXV0dNm3ahHXr1uH06dO44YYblMevWbMG11xzDS699FLs378f33zzDebMmeP1M/785z9jzpw52L9/P37yk5/gnnvuwfHjx3scPxH1YtDOYSaioLJ48WLxwQcf9LpNPrr+s88+6/XxkyZNEv/2t78p32dkZIgvvPCC8j0A8Ve/+pXyfUtLiygIgvjll196/az6+npRFEXxjTfeEAGIubm5ymNefvllMTExUfk+MTFR/OMf/6h8b7fbxfT0dPHKK6/sdpy33HKLeOedd3rdtmXLFlGlUont7e3K2C+++GKva2644QZx+fLloiiK4tdffy2q1Wqvo+lzcnJEAOKuXbtEURTF+fPniytWrOh2HBkZGeL3v/995Xun0ykmJCSIr7zySrePIaLesaJCdAbqXAlobW3FY489hkmTJiEqKgomkwnHjx/vtaIybdo05c9GoxFmsxlVVVXdXm8wGDBmzBjl++TkZOX6xsZGVFZW4qyzzlLuV6vVmD17do9j2Lt3L958802YTCbl66KLLoLT6UR+fr5y3fz5870eN3/+fBw7dgwAcOzYMaSlpXlVneS/C/maAwcO4Pzzz+9xLJ5/H4IgICkpqce/DyLqHZtpic5AnVfv/OxnP8PatWvxpz/9CdnZ2QgPD8e1114Lq9Xa4/OEhYV5fS8IApxOZ5+uF0Wxy22eOt/fmdPpxF133YUHHnigy33p6ek9Plb+WaIodvm5nW8PDw/v8bmAvv99EFHvWFEhGqG0Wi0cDodf127ZsgW33347rr76akydOhVJSUkoKCgY2gF2EhkZicTEROzatUu5zeFwYP/+/T0+btasWcjJyUF2dnaXL61Wq1y3Y8cOr8ft2LEDEyZMACBVT4qKilBcXKzcf/ToUTQ2NmLixIkApGrJN998M+DXSUR9w4oK0QiVmZmJnTt3oqCgACaTCTExMd1em52djVWrVuHyyy+HIAh48sknA1IJuP/++7Fy5UpkZ2djwoQJ+Nvf/ob6+nqf1Q7Z448/jrPPPhv33nsv7rjjDhiNRhw7dgzr1q3zWtnz3Xff4bnnnsNVV12FdevW4aOPPsKaNWsAABdccAGmTZuGFStW4MUXX4TdbsdPfvITLF68WJkme+qpp3D++edjzJgxuPHGG2G32/Hll1/iscceG9q/FKIzHCsqRCPUo48+CrVajUmTJiE+Pr7HfpMXXngB0dHRWLBgAS6//HJcdNFFmDVr1jCOVvL444/jpptuwq233or58+cr/SZ6vb7bx0ybNg2bNm3CqVOncO6552LmzJl48sknkZyc7HXdI488gr1792LmzJl49tln8ec//xkXXXQRAGmK5rPPPkN0dDQWLVqECy64AKNHj8aHH36oPH7JkiX46KOPsHr1asyYMQNLly7Fzp07h+YvgogUgtjbBDARUYA4nU5MnDgR119/PZ599tl+P09mZiYeeughPPTQQ4M3OCIaFpz6IaKgUVhYiK+//hqLFy+GxWLBSy+9hPz8fNx8882BHhoRBQinfogoaKhUKrz55puYO3cuFi5ciMOHD2P9+vVKQysRnXk49UNERERBixUVIiIiCloMKkRERBS0GFSIiIgoaDGoEBERUdBiUCEiIqKgxaBCREREQYtBhYiIiIIWgwoREREFrf8P/VpcsTOmJeAAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "\"\"\"\n",
    "部分代码参考了GitHub项目d2l-ai/d2l-zh的思路\n",
    "（Copyright (c) 2022 Aston Zhang, Zachary C. Lipton,\n",
    "Mu Li, and Alexander J. Smola, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 多头注意力循环神经网络\n",
    "class MultiHeadAttentionRNN(AttentionRNN):\n",
    "    def __init__(self, input_size, hidden_size, num_heads=4):\n",
    "        super().__init__(input_size, hidden_size)\n",
    "        # 简单起见，一般要求hidden_size能够被num_heads整除\n",
    "        assert hidden_size % num_heads == 0\n",
    "        self.num_heads = num_heads\n",
    "        # 多头注意力参数，用于将查询、键、值映射到子空间\n",
    "        self.W_aq = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_aq = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_ak = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_ak = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_av = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_av = nn.Parameter(torch.zeros(hidden_size))\n",
    "        self.W_ac = nn.Parameter(normal((hidden_size, hidden_size)))\n",
    "        self.b_ac = nn.Parameter(torch.zeros(hidden_size))\n",
    "\n",
    "    # 多头缩放点乘注意力\n",
    "    def attention(self, query, keys, values):\n",
    "        \"\"\"\n",
    "        query: batch_size * hidden_size\n",
    "        keys/values: batch_size * prev_len * hidden_size\n",
    "        \"\"\"\n",
    "        query = torch.mm(query, self.W_aq) + self.b_aq\n",
    "        ori_shape = keys.size()\n",
    "        \n",
    "        keys = torch.reshape(torch.mm(torch.flatten(keys, \n",
    "                start_dim=0, end_dim=1), self.W_ak) + \n",
    "                self.b_ak, ori_shape)\n",
    "        values = torch.reshape(torch.mm(torch.flatten(values, \n",
    "                start_dim=0, end_dim=1), self.W_av) + \n",
    "                self.b_av, ori_shape)\n",
    "        # batch_size * 1 * hidden_size\n",
    "        query = torch.unsqueeze(query, 1)\n",
    "        # batch_size * hidden_size * prev_len\n",
    "        keys = torch.permute(keys, (0, 2, 1))\n",
    "        \n",
    "        head_size = self.hidden_size // self.num_heads\n",
    "        query = torch.split(query, head_size, 2)\n",
    "        keys = torch.split(keys, head_size, 1)\n",
    "        values = torch.split(values, head_size, 2)\n",
    "        \n",
    "        heads = []\n",
    "        for i in range(self.num_heads):\n",
    "            # batch_size * 1 * prev_len\n",
    "            head_scores = torch.bmm(query[i], keys[i]) / np.sqrt(\n",
    "                self.hidden_size // self.num_heads) \n",
    "            # batch_size * 1 * prev_len\n",
    "            head_weights = F.softmax(head_scores, dim=1)\n",
    "            # batch_size * head_size\n",
    "            head_state = torch.squeeze(torch.bmm(head_weights, \n",
    "                values[i])) \n",
    "            heads.append(head_state)\n",
    "        heads = torch.cat(heads, dim=1)        \n",
    "        attention_state = torch.mm(heads, self.W_ac) + self.b_ac\n",
    "\n",
    "        return attention_state\n",
    "\n",
    "data_loader = DataLoader(torch.tensor(sent_tokens, \n",
    "    dtype=torch.long), batch_size=16, shuffle=True)\n",
    "\n",
    "mha_rnn = MultiHeadAttentionRNN(128, 128)\n",
    "train_rnn_lm(data_loader, mha_rnn, vocab_size, hidden_size=128, \n",
    "    epochs=200, learning_rate=1e-3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "166d4dce",
   "metadata": {},
   "source": [
    "下面来实现Transformer模型，包括加入了位置编码的嵌入层、缩放点乘注意力、多头注意力、层归一化等具体实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "0e4110a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "\"\"\"\n",
    "代码修改自GitHub项目huggingface/transformers\n",
    "（Copyright (c) 2020, The HuggingFace Team, Apache-2.0 License（见附录））\n",
    "\"\"\"\n",
    "# 实现Transformer模型\n",
    "class EmbeddingLayer(nn.Module):\n",
    "    def __init__(self, vocab_size, max_len, embed_size):\n",
    "        super().__init__()\n",
    "        self.vocab_size = vocab_size\n",
    "        self.max_len = max_len\n",
    "        self.embed_size = embed_size\n",
    "        self.word_embedding = nn.Embedding(vocab_size, embed_size)\n",
    "        self.pos_embedding = nn.Embedding(max_len, embed_size)\n",
    "        \n",
    "    def forward(self, input_ids, pos_ids):\n",
    "        \"\"\"\n",
    "        input_ids/pos_ids: batch_size * seq_len\n",
    "        return: batch_size * seq_len * embed_size\n",
    "        \"\"\"\n",
    "        word_embed = self.word_embedding(input_ids)\n",
    "        pos_embed = self.pos_embedding(pos_ids)\n",
    "        # 将词嵌入和位置嵌入相加得到嵌入层输出\n",
    "        return word_embed + pos_embed\n",
    "\n",
    "# 缩放点乘注意力\n",
    "class ScaledDotProductAttention(nn.Module):\n",
    "    def __init__(self, dropout):\n",
    "        super().__init__()\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "    \n",
    "    def forward(self, queries, keys, values, attention_mask):\n",
    "        \"\"\"\n",
    "        queries/keys/values: batch_size * seq_len * hidden_size\n",
    "        attention_mask: batch_size * seq_len * seq_len\n",
    "        return: batch_size * seq_len * hidden_size\n",
    "        \"\"\"\n",
    "        d = queries.size(-1)\n",
    "        # 根据点乘注意力的矩阵形式计算注意力分数，除以查询向量或键向量\n",
    "        # 维度的平方根，即为缩放点乘注意力\n",
    "        scores = torch.bmm(queries, torch.transpose(keys, 1, 2)) / np.sqrt(d)\n",
    "        # 将掩码为0的位置的注意力分数设为一个大负数，根据softmax函数\n",
    "        # 的性质，这些注意力分数归一化后接近0\n",
    "        scores[attention_mask == 0] = -1e6\n",
    "        self.attention_weights = F.softmax(scores, dim=-1)\n",
    "        return torch.bmm(self.dropout(self.attention_weights), values)\n",
    "    \n",
    "class MultiHeadSelfAttention(nn.Module):\n",
    "    def __init__(self, hidden_size, num_heads, dropout):\n",
    "        super().__init__()\n",
    "        assert hidden_size % num_heads == 0\n",
    "        self.hidden_size = hidden_size\n",
    "        self.num_heads = num_heads\n",
    "        self.W_q = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_k = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_v = nn.Linear(hidden_size, hidden_size)\n",
    "        self.W_o = nn.Linear(hidden_size, hidden_size)\n",
    "        self.attention = ScaledDotProductAttention(dropout)\n",
    "    \n",
    "    def transpose_qkv(self, states):\n",
    "        # 将长度为hidden_size的向量分成num_heads个长度相等的向量\n",
    "        states = states.reshape(states.shape[0], states.shape[1],\\\n",
    "            self.num_heads, self.hidden_size // self.num_heads)\n",
    "        states = torch.permute(states, (0, 2, 1, 3))\n",
    "        return states.reshape(-1, states.shape[2], states.shape[3])\n",
    "    \n",
    "    # 与transpose_qkv的变换相反\n",
    "    def transpose_output(self, states):\n",
    "        states = states.reshape(-1, self.num_heads, states.shape[1],\\\n",
    "            states.shape[2])\n",
    "        states = torch.permute(states, (0, 2, 1, 3))\n",
    "        return states.reshape(states.shape[0], states.shape[1], -1)\n",
    "    \n",
    "    def forward(self, queries, keys, values, attention_mask):\n",
    "        \"\"\"\n",
    "        querys/keys/values: batch * seq_len * hidden_size\n",
    "        attention_mask: batch * seq_len * seq_len\n",
    "        return:\n",
    "        \"\"\"\n",
    "        # (batch_size * num_heads) * seq_len * (hidden_size / num_heads)\n",
    "        queries = self.transpose_qkv(self.W_q(queries))\n",
    "        keys = self.transpose_qkv(self.W_k(keys))\n",
    "        values = self.transpose_qkv(self.W_v(values))\n",
    "        # 重复张量的元素，用以支持多个注意力头的运算\n",
    "        # (batch_size * num_heads) * seq_len * seq_len\n",
    "        attention_mask = torch.repeat_interleave(attention_mask,\\\n",
    "            repeats=self.num_heads, dim=0)\n",
    "        # (batch_size * num_heads) * seq_len * (hidden_size / num_heads)\n",
    "        output = self.attention(queries, keys, values, attention_mask)\n",
    "        # batch * seq_len * hidden_size\n",
    "        output_concat = self.transpose_output(output)\n",
    "        return self.W_o(output_concat)\n",
    "\n",
    "# 两层前馈神经网络\n",
    "class PositionWiseFNN(nn.Module):\n",
    "    def __init__(self, hidden_size, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.dense1 = nn.Linear(hidden_size, intermediate_size)\n",
    "        self.relu = nn.ReLU()\n",
    "        self.dense2 = nn.Linear(intermediate_size, hidden_size)\n",
    "        \n",
    "    def forward(self, X):\n",
    "        return self.dense2(self.relu(self.dense1(X)))\n",
    "\n",
    "# 层归一化\n",
    "class LayerNorm(nn.Module):\n",
    "    def __init__(self, normalized_shape, eps=1e-6):\n",
    "        super().__init__()\n",
    "        self.gamma = nn.Parameter(torch.ones(normalized_shape))\n",
    "        self.beta = nn.Parameter(torch.zeros(normalized_shape))\n",
    "        # 一个小量用于数值稳定（防止除0）\n",
    "        self.eps = eps\n",
    "        \n",
    "    def forward(self, hidden_states):\n",
    "        mean = torch.mean(hidden_states, -1, keepdim=True)\n",
    "        std = torch.std(hidden_states, -1, keepdim=True)\n",
    "        return self.gamma * (hidden_states - mean) / (std +\\\n",
    "            self.eps) + self.beta\n",
    "\n",
    "# 将两个输入相加并归一化\n",
    "class AddNorm(nn.Module):\n",
    "    def __init__(self, hidden_size, dropout):\n",
    "        super().__init__()\n",
    "        self.dropout = nn.Dropout(dropout)\n",
    "        self.layer_norm = LayerNorm(hidden_size)\n",
    "        \n",
    "    def forward(self, X, Y):\n",
    "        return self.layer_norm(self.dropout(Y) + X)\n",
    "    \n",
    "# 一个完整的Transformer层\n",
    "class TransformerLayer(nn.Module):\n",
    "    def __init__(self, hidden_size, num_heads, dropout, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.self_attention = MultiHeadSelfAttention(hidden_size,\\\n",
    "            num_heads, dropout)\n",
    "        self.add_norm1 = AddNorm(hidden_size, dropout)\n",
    "        self.fnn = PositionWiseFNN(hidden_size, intermediate_size)\n",
    "        self.add_norm2 = AddNorm(hidden_size, dropout)\n",
    "    \n",
    "    def forward(self, X, attention_mask):\n",
    "        Y = self.add_norm1(X, self.self_attention(X, X, X, attention_mask))\n",
    "        return self.add_norm2(Y, self.fnn(Y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2fd3f8f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 在Transformer模型基础上加上语言模型需要的输入输出、损失计算等\n",
    "class TransformerLM(nn.Module):\n",
    "    def __init__(self, vocab_size, max_len, hidden_size, num_layers,\\\n",
    "                 num_heads, dropout, intermediate_size):\n",
    "        super().__init__()\n",
    "        self.embedding_layer = EmbeddingLayer(vocab_size, max_len,\\\n",
    "            hidden_size)\n",
    "        self.num_layers = num_layers\n",
    "        # 使用ModuleList保存多个Transformer层，注意不能使用Python列表，\n",
    "        # Python列表保存的PyTorch变量无法自动求导\n",
    "        self.layers = nn.ModuleList([TransformerLayer(hidden_size,\\\n",
    "            num_heads, dropout, intermediate_size)\\\n",
    "            for _ in range(num_layers)])\n",
    "        self.output_layer = nn.Linear(hidden_size, vocab_size)\n",
    "        \n",
    "    def forward(self, input_ids):\n",
    "        # 这里实现的forward()函数一次只能处理一句话，\n",
    "        # 如果想要支持批次运算，实现起来会更复杂，也会引入冗余操作\n",
    "        seq_len = input_ids.size(0)\n",
    "        assert input_ids.ndim == 1 and seq_len <= \\\n",
    "            self.embedding_layer.max_len\n",
    "        \n",
    "        # 1 * seq_len\n",
    "        input_ids = torch.unsqueeze(input_ids, dim=0)\n",
    "        pos_ids = torch.unsqueeze(torch.arange(seq_len), dim=0)\n",
    "        # 定义下三角掩码，用于语言模型训练\n",
    "        # 1 * seq_len * seq_len\n",
    "        attention_mask = torch.unsqueeze(torch.tril(torch.ones((seq_len,\\\n",
    "            seq_len), dtype=torch.int32)), dim=0)\n",
    "        # 1 * seq_len * hidden_size\n",
    "        hidden_states = self.embedding_layer(input_ids, pos_ids)\n",
    "        for layer in self.layers:\n",
    "            hidden_states = layer(hidden_states, attention_mask)\n",
    "        outputs = self.output_layer(hidden_states)\n",
    "        \n",
    "        loss_fct = nn.CrossEntropyLoss(ignore_index=0)\n",
    "        loss = loss_fct(outputs[:, :-1].squeeze(),\\\n",
    "            input_ids[:, 1:].squeeze())\n",
    "        return loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "e459fc19",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "epoch-49, loss=0.8899: 100%|█| 50/50 [09:59<00:00, 11.99s/it\n"
     ]
    },
    {
     "data": {
      "image/png": "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CgUUCgUiIiLw0UcfQaFQGM4rz7lpODo6on///khKSjL5v28GlVvY2tpiyJAhOHDgQK3HDxw4gFGjRklUlXXo1q0bfH19a537yspKRERE8Ny3kiiKePbZZ7Fjxw788ccf6NatW63nec5NTxRFqNVqnmsTmDhxIuLj4xEXF2e4DR06FPPnz0dcXBy6d+/Oc25CarUaiYmJ8PPzM/2/7za343YwW7ZsEW1sbMSNGzeKFy5cEJcuXSo6OjqKqampUpfW7hUXF4uxsbFibGysCEBctWqVGBsbK6alpYmiKIorV64UXV1dxR07dojx8fHivHnzRD8/P1GlUklcefv09NNPi66uruLhw4fFrKwsw62srMxwDM+58SxfvlyMjIwUU1JSxHPnzon//Oc/RZlMJu7fv18URZ5rc7h11o8o8pwb0wsvvCAePnxYvHr1qhgVFSXefffdorOzs+G70ZTnmkGlHmvXrhW7dOki2traioMHDzZM56S2OXTokAigzu3RRx8VRbF6iturr74q+vr6ikqlUhw3bpwYHx8vbdHtWH3nGoD45ZdfGo7hOTeehQsXGn5veHl5iRMnTjSEFFHkuTaHvwYVnnPjmTt3rujn5yfa2NiI/v7+4qxZs8SEhATD86Y814IoimLbx2WIiIiIjI89KkRERGSxGFSIiIjIYjGoEBERkcViUCEiIiKLxaBCREREFotBhYiIiCwWgwoRERFZLAYVIiIislgMKkTULF27dsUHH3zQ7OMPHz4MQRBQWFhosposSUvPDxE1j0LqAojINCZMmICBAwca7cvz9OnTcHR0bPbxo0aNQlZWFlxdXY3y+URknRhUiKyYKIrQarVQKJr+VeDl5dWi97a1tTVs/05E1Fq89EPUAS1YsAARERH48MMPIQgCBEFAamqq4XLMvn37MHToUCiVShw5cgTJycmYMWMGfHx84OTkhGHDhuHgwYO13vOvlzYEQcDnn3+Oe++9Fw4ODujRowd27dpleP6vl342bdoENzc37Nu3D3369IGTkxPuuOMOZGVlGV6j0WiwePFiuLm5wcPDA6+88goeffRRzJw5s9Gf9/jx4xg3bhzs7e0RFBSExYsXo7S0tFbtb7zxBh588EE4OTnB398fH3/8ca33SE9Px4wZM+Dk5AQXFxfMmTMHOTk5tY7ZtWsXhg4dCjs7O3h6emLWrFm1ni8rK8PChQvh7OyMzp07Y8OGDY3WTURNY1Ah6oA+/PBDhIeH4/HHH0dWVhaysrIQFBRkeP7ll1/GihUrkJiYiLCwMJSUlODOO+/EwYMHERsbi6lTp2L69OlIT09v9HNef/11zJkzB+fOncOdd96J+fPno6CgoMHjy8rK8N577+Gbb75BZGQk0tPT8eKLLxqef/vtt/Htt9/iyy+/xLFjx6BSqbBz585Ga4iPj8fUqVMxa9YsnDt3Dlu3bsXRo0fx7LPP1jru3XffRVhYGM6cOYPly5fj+eefx4EDBwBUjyzNnDkTBQUFiIiIwIEDB5CcnIy5c+caXr97927MmjULd911F2JjY/H7779j6NChtT7j/fffx9ChQxEbG4tnnnkGTz/9NC5evNho/UTUBKPswUxEFuevW96LoigeOnRIBCDu3LmzydeHhoaKH3/8seF+ly5dxNWrVxvuAxD//e9/G+6XlJSIgiCIe/bsqfVZN2/eFEVRFL/88ksRgHjlyhXDa9auXSv6+PgY7vv4+Ijvvvuu4b5GoxE7d+4szpgxo8E6H374YfGJJ56o9diRI0dEmUwmlpeXG2q/4447ah0zd+5ccdq0aaIoiuL+/ftFuVwupqenG55PSEgQAYinTp0SRVEUw8PDxfnz5zdYR5cuXcSHHnrIcF+n04ne3t7iunXrGnwNETWNIypEVuivIwGlpaV4+eWXERoaCjc3Nzg5OeHixYtNjqiEhYUZ/tvR0RHOzs7Izc1t8HgHBwcEBwcb7vv5+RmOLyoqQk5ODoYPH254Xi6XY8iQIY3WEBMTg02bNsHJyclwmzp1KnQ6HVJSUgzHhYeH13pdeHg4EhMTAQCJiYkICgqqNeqkPxf6Y+Li4jBx4sRGa7n1fAiCAF9f30bPBxE1jc20RFbor7N3XnrpJezbtw/vvfceQkJCYG9vj9mzZ6OysrLR97Gxsal1XxAE6HS6Fh0vimKdx2711+f/SqfT4cknn8TixYvrPNe5c+dGX6v/LFEU63zuXx+3t7dv9L2Alp8PImoaR1SIOihbW1totdpmHXvkyBEsWLAA9957L/r37w9fX1+kpqaatsC/cHV1hY+PD06dOmV4TKvVIjY2ttHXDR48GAkJCQgJCalzs7W1NRwXFRVV63VRUVHo3bs3gOrRk/T0dGRkZBiev3DhAoqKitCnTx8A1aMlv//+e5t/TiJqGY6oEHVQXbt2xcmTJ5GamgonJye4u7s3eGxISAh27NiB6dOnQxAE/Oc//5FkJOC5557DihUrEBISgt69e+Pjjz/GzZs36x3t0HvllVcwcuRILFq0CI8//jgcHR2RmJiIAwcO1JrZc+zYMbzzzjuYOXMmDhw4gG3btmH37t0AgEmTJiEsLAzz58/HBx98AI1Gg2eeeQbjx483XCZ79dVXMXHiRAQHB+OBBx6ARqPBnj178PLLL5v2pBBZOY6oEHVQL774IuRyOUJDQ+Hl5dVov8nq1avRqVMnjBo1CtOnT8fUqVMxePBgM1Zb7ZVXXsG8efPwyCOPIDw83NBvYmdn1+BrwsLCEBERgaSkJIwdOxaDBg3Cf/7zH/j5+dU67oUXXkBMTAwGDRqEN954A++//z6mTp0KoPoSzc6dO9GpUyeMGzcOkyZNQvfu3bF161bD6ydMmIBt27Zh165dGDhwIG6//XacPHnSNCeCiAwEsakLwEREEtHpdOjTpw/mzJmDN954o9Xv07VrVyxduhRLly41XnFEZBa89ENEFiMtLQ379+/H+PHjoVarsWbNGqSkpODBBx+UujQikggv/RCRxZDJZNi0aROGDRuG0aNHIz4+HgcPHjQ0tBKR9eGlHyIiIrJYHFEhIiIii8WgQkRERBaLQYWIiIgsFoMKERERWSwGFSIiIrJYDCpERERksRhUiIiIyGIxqBAREZHF+n+Y/C2IdT1c3wAAAABJRU5ErkJggg==",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 训练TransformerLM，由于不再采取批次训练，因此不再使用RNNLM和data_loader\n",
    "def train_transformer_lm(data, model, epochs=50, learning_rate=1e-3):\n",
    "    optimizer = Adam(model.parameters(), lr=learning_rate)\n",
    "    model.zero_grad()\n",
    "    model.train()\n",
    "    \n",
    "    epoch_loss = []\n",
    "    with trange(epochs, desc='epoch', ncols=60) as pbar:\n",
    "        for epoch in pbar:\n",
    "            step_loss = []\n",
    "            np.random.shuffle(data)\n",
    "            for step, x in enumerate(data):\n",
    "                loss = model(torch.tensor(x, dtype=torch.long))\n",
    "                pbar.set_description(f'epoch-{epoch},'+\\\n",
    "                    f' loss={loss.item():.4f}')\n",
    "                loss.backward()\n",
    "                grad_clipping(model)\n",
    "                optimizer.step()\n",
    "                model.zero_grad()\n",
    "                step_loss.append(loss.item())\n",
    "            # 本章前面的模型训练使用batch_size为16，\n",
    "            # TransformerLM出于简便实现只能使用batch_size为1\n",
    "            # 因此TransformerLM每一步的损失方差会更大，\n",
    "            # 为便于对比，取每个epoch最后16个样本的平均损失\n",
    "            epoch_loss.append(np.mean(step_loss[-16:]))\n",
    "    \n",
    "    epoch_loss = np.array(epoch_loss)\n",
    "    plt.plot(range(len(epoch_loss)), epoch_loss)\n",
    "    plt.xlabel('training epoch')\n",
    "    plt.ylabel('loss')\n",
    "    plt.show()\n",
    "    \n",
    "sent_tokens = dataset.convert_tokens_to_ids()\n",
    "max_len=40\n",
    "for i, tokens in enumerate(sent_tokens):\n",
    "    tokens = tokens[:max_len]\n",
    "    tokens += [0] * (max_len - len(tokens))\n",
    "    sent_tokens[i] = tokens\n",
    "sent_tokens = np.array(sent_tokens)\n",
    "\n",
    "model = TransformerLM(vocab_size, max_len=40, hidden_size=128,\\\n",
    "    num_layers=1, num_heads=4, dropout=0., intermediate_size=512)\n",
    "train_transformer_lm(sent_tokens, model)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c4f9ed8a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
